const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
const userModel = require('../models/users.model')

const logger = require('../utils/logger')
const HttpException = require('../utils/HttpException')
const { isEmpty } = require('../utils/index')
const config = require('../config')

class AuthService {
  users = userModel

  async signUp (userData) {
    if (isEmpty(userData)) {
      throw new HttpException(400, '请填写正确的参数');
    }

    const user = await this.users.findOne({ username: userData.username })

    if (user) {
      throw new HttpException(409, `用户名 ${userData.username} 已存在`)
    }
    // console.log(JSON.parse(userData))
    const hashedPassword = await bcrypt.hash(userData.password, 10)
    if (userData.role === 'admin') {
      throw new HttpException(403, '不能注册为管理员');
    }

    const config = require('../../config.json')
    const curUserCount = await this.users.countDocuments({})
    if (curUserCount >= (config.maxUsers || Number.MIN_SAFE_INTEGER)) {
      throw new HttpException(409, '用户数已达上限，请联系管理员');
    }

    const createdUser = await this.users.create({ ...userData, password: hashedPassword })
    logger.info('user created ', createdUser.username, createdUser._id)
    return createdUser
  }

  async signIn (userData) {
    if (isEmpty(userData)) {
      throw new HttpException(400, '请填写正确的参数');
    }

    const user = await this.users.findOne({ username: userData.username })

    if (!user) {
      throw new HttpException(409, `用户名 ${userData.username} 不存在`)
    }

    const isPasswordMatching = await bcrypt.compare(userData.password, user.password)

    if (!isPasswordMatching) {
      throw new HttpException(409, `密码不正确`)
    }
    const token = this.createToken(user)

    logger.info('user signin ', user.username, user._id)

    return { ...user._doc, token: token }
  }
  async signOut () {
    // todo 修改token的salt
    const user = {}
    logger.info('user signout ', user.username, user._id)
  }
  createToken (user) {
    const dataStoredInToken = { _id: user._id, username: user.username, role: user.role, area: user.area };
    const expiresIn = 60 * 60 * 24;

    return jwt.sign(dataStoredInToken, config.secretKey, { expiresIn })
  }
}

module.exports = AuthService